[EventTiming] Attempt to fix some flaky tests This CL attempts to fix test flakiness. * For the click counts, remove tests about mouseout/mouseover since those could fail under certain starting positions of the mouse, and the test has a pretty high flakiness score right now. * For other tests, fix flakiness by making sure that PerformanceObserver callbacks where mousedown is not present are ignored. This is possible since a click triggers mousedown, mouseup, click, etc., so we cannot just assume that mousedown will always be present at the callback. Bug: 1074048 Change-Id: I95a082948c105cf18b51376c9d6421195b23b718 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2163775 Reviewed-by: Yoav Weiss <yoavweiss@chromium.org> Commit-Queue: Nicolás Peña Moreno <npm@chromium.org> Cr-Commit-Position: refs/heads/master@{#763352} diff --git a/event-timing/crossiframe.html b/event-timing/crossiframe.html index 0376fb9..dfbd289 100644 --- a/event-timing/crossiframe.html +++ b/event-timing/crossiframe.html
@@ -51,13 +51,18 @@ promise_test(async t => { assert_implements(window.PerformanceEventTiming, "Event Timing is not supported"); clickTimeMin = performance.now(); - let observedEntries = false; + let observedMouseDown = false; const observerPromise = new Promise(resolve => { new PerformanceObserver(t.step_func(entries => { - assert_false(observedEntries, + const mouseDowns = entries.getEntriesByName('mousedown'); + // Ignore the callback if there were no mousedown entries. + if (mouseDowns.length === 0) + return; + + assert_false(observedMouseDown, "Observer of main frames should only capture main-frame event-timing entries"); - validateEntries(entries.getEntriesByName('mousedown')); - observedEntries = true; + validateEntries(mouseDowns); + observedMouseDown = true; resolve(); })).observe({type: 'event'}); }); diff --git a/event-timing/event-click-counts.html b/event-timing/event-click-counts.html index d4e87c5..6c6563b 100644 --- a/event-timing/event-click-counts.html +++ b/event-timing/event-click-counts.html
@@ -22,10 +22,6 @@ assert_equals(clickCount, expectedCount,'Incorrect click count.'); assert_equals(performance.eventCounts.get('mousedown'), expectedCount, 'Incorrect mousedown count'); assert_equals(performance.eventCounts.get('mouseup'), expectedCount, 'Incorrect mouseup count.'); - assert_equals(performance.eventCounts.get('mouseover'), expectedCount, 'Incorrect mouseover count.'); - if (expectedCount != 1) { - assert_equals(performance.eventCounts.get('mouseout'), expectedCount - 1, 'Incorrect mouseout count.'); - } resolve(); } function promiseClicks(expectedCount) { diff --git a/event-timing/event-retarget.html b/event-timing/event-retarget.html index 130e700..29c114f 100644 --- a/event-timing/event-retarget.html +++ b/event-timing/event-retarget.html
@@ -23,12 +23,16 @@ }; } }); - const observer = new PerformanceObserver(t.step_func_done((entryList) => { - const entries = entryList.getEntries().filter(e => e.name === 'mousedown'); - // There must only be one click entry. + const observer = new PerformanceObserver(t.step_func((entryList) => { + const entries = entryList.getEntriesByName('mousedown'); + if (entries.length === 0) + return; + + // There must only be one mousedown entry. assert_equals(entries.length, 1); verifyClickEvent(entries[0], 'custom_button', true); assert_true(innerButtonClicked); + t.done() })); observer.observe({entryTypes: ['event']}); clickAndBlockMain('custom_button'); diff --git a/event-timing/programmatic-click-not-observed.html b/event-timing/programmatic-click-not-observed.html index b5b1683..4060d2d 100644 --- a/event-timing/programmatic-click-not-observed.html +++ b/event-timing/programmatic-click-not-observed.html
@@ -17,25 +17,35 @@ while(performance.now() < end) {} delayCalled = true; } - async_test(function(t) { + promise_test(function(t) { assert_implements(window.PerformanceEventTiming, 'Event Timing is not supported.'); - const observer = new PerformanceObserver(t.step_func_done((entryList) => { - const entries = entryList.getEntries().filter(e => e.name === 'mousedown'); - // There must only be one click entry: from the clickAndBlockMain() call. - assert_equals(entries.length, 1); - const entry = entries[0]; - // This ensures that the entry is exposing timing from the second click, i.e. - // the one from the clickAndBlockMain() call. - assert_greater_than_equal(entry.processingStart, beforeClick); - verifyClickEvent(entry, 'div2', true); - })); - observer.observe({entryTypes: ['event']}); + let observedMouseDown = false; + const observerPromise = new Promise(resolve => { + const observer = new PerformanceObserver(t.step_func(entryList => { + const mouseDowns = entryList.getEntriesByName('mousedown'); + // Ignore cases in which there is no mousedown. + if (mouseDowns.length === 0) + return; + + assert_false(observedMouseDown, 'There must only be one mousedown entry.'); + assert_equals(mouseDowns.length, 1); + const entry = mouseDowns[0]; + // This ensures that the entry is exposing timing from the second click, i.e. + // the one from the clickAndBlockMain() call. + assert_greater_than_equal(entry.processingStart, beforeClick); + verifyClickEvent(entry, 'div2', true); + observedMouseDown = true; + resolve(); + })); + observer.observe({entryTypes: ['event']}); + }); document.getElementById('div').click(); // Take the timestamp after the programmatic click but before the next click. beforeClick = performance.now(); // After the programmatic click, use another input to know when entries have been // dispatched to the PerformanceObserver callback. - clickAndBlockMain('div2'); + const clickPromise = clickAndBlockMain('div2'); + return Promise.all([observerPromise, clickPromise]); }, "Event Timing: events from programmatic click are not observed"); </script> </html> diff --git a/event-timing/retrievability.html b/event-timing/retrievability.html index 087cd13..d5a9c04 100644 --- a/event-timing/retrievability.html +++ b/event-timing/retrievability.html
@@ -31,9 +31,11 @@ */ async_test(function(t) { assert_implements(window.PerformanceEventTiming, 'Event Timing is not supported.'); - new PerformanceObserver(t.step_func_done(() => { - validateEntries(); - t.done(); + new PerformanceObserver(t.step_func(entryList => { + if (entryList.getEntriesByName('mousedown')) { + validateEntries(); + t.done(); + } })).observe({entryTypes: ['event']}); clickAndBlockMain('button'); }, "Event Timing: make sure event-timing entries are not retrievable by performance.getEntries*."); diff --git a/event-timing/timingconditions.html b/event-timing/timingconditions.html index e7763c4..5f4448c 100644 --- a/event-timing/timingconditions.html +++ b/event-timing/timingconditions.html
@@ -32,28 +32,38 @@ target.focus(); } - async_test(function(t) { + promise_test(function(t) { assert_implements(window.PerformanceEventTiming, 'Event Timing is not supported.'); - new PerformanceObserver(t.step_func_done(entryList => { - const observerCallbackTime = performance.now(); - const entries = entryList.getEntries().filter( - entry => entry.name === 'mousedown'); - assert_equals(entries.length, 1, - "Should only observe one entry: " + - JSON.stringify(entries) + "."); - assert_equals(entries[0].name, 'mousedown', - "The observed entry should be a click"); - assert_less_than(entries[0].startTime, observerCallbackTime, - "The startTime should be before observerCallbackTime"); - assert_greater_than(entries[0].startTime, trustedClickStart, - "The startTime should be after trustedClickStart"); - })).observe({ entryTypes: ['event'] }); + let observedMouseDown = false; + const observerPromise = new Promise(resolve => { + new PerformanceObserver(t.step_func(entryList => { + const observerCallbackTime = performance.now(); + const mouseDowns = entryList.getEntriesByName('mousedown'); + // Ignore cases in which there is no mousedown. + if (mouseDowns.length === 0) + return; + + assert_false(observedMouseDown, 'Got more than one callback with mousedown.'); + assert_equals(mouseDowns.length, 1, + "Should only observe one mousedown entry. Instead, got these: " + + JSON.stringify(mouseDowns) + "."); + assert_equals(mouseDowns[0].name, 'mousedown', + "The observed entry should be a mousedown"); + assert_less_than(mouseDowns[0].startTime, observerCallbackTime, + "The startTime should be before observerCallbackTime"); + assert_greater_than(mouseDowns[0].startTime, trustedClickStart, + "The startTime should be after trustedClickStart"); + observedMouseDown = true; + resolve(); + })).observe({ entryTypes: ['event'] }); + }); // Untrusted event of a type event timing cares about. untrustedClickAndBlockMain('button'); // Trusted event of a type event timing doesn't cares about. trustedFocusAndBlockMain('button'); // Trusted event of a type event timing cares about. - trustedClickAndBlockMain('button').then(wait); + const clickPromise = trustedClickAndBlockMain('button').then(wait); + return Promise.all([observerPromise, clickPromise]); }, "Event Timing only times certain types of trusted event."); </script> </html>